package com.socket.learing.transfer;

import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.ByteBuffer;

/**
 * 服务广播监听
 */
@Slf4j
public class DatagramService implements Runnable {

    private DatagramSocket datagramService;

    private boolean flag;

    public DatagramService() {
        try {
            this.datagramService = new DatagramSocket(CommonConstant.SERVICE_DATAGRAM_PORT);
            this.flag = true;
        } catch (SocketException e) {
            log.error("创建datagramService异常");
        }
    }

    @Override
    public void run() {
        while (flag) {
            try {
                listener();
            } catch (IOException e) {
                log.error("监听器异常:{}", e);
            }
        }
    }

    public void listener() throws IOException {
        if (datagramService == null) {
            return;
        }
        byte[] bytes = new byte[512];
        DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);
        datagramService.receive(datagramPacket);
        ByteBuffer byteBuffer = ByteBuffer.wrap(datagramPacket.getData(), 0, datagramPacket.getData().length);
        short receivablePort = byteBuffer.getShort();
        /*添加用户信息*/
        UserInfo userInfo = new UserInfo(datagramPacket.getAddress(), receivablePort);
        addService(userInfo);
        response(userInfo);
    }

    /**
     * 进行服务响应，回复IP及绑定端口号信息
     */
    public void response(UserInfo userInfo) throws IOException {
        byte[] bytes = new byte[512];
        DatagramPacket response = new DatagramPacket(bytes, 0, bytes.length);
        ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[512]);
        byteBuffer.putInt(CommonConstant.TRANSFER_SERVICE_PORT);
        response.setData(byteBuffer.array(), 0, byteBuffer.limit());
        response.setAddress(userInfo.getIp());
        response.setPort(userInfo.getPort());
        datagramService.send(response);
        log.info("消息回送完成");
    }


    /**
     * 关闭监听
     */
    public void close() {
        this.flag = false;
        if (null != datagramService) {
            datagramService.close();
        }
    }

    public void addService(UserInfo userInfo) {
        for (UserInfo user : CommonConstant.SERVICE_USER_INFOS) {
            if (userInfo.getPort() == user.getPort()) {
                return;
            }
        }
        CommonConstant.SERVICE_USER_INFOS.add(userInfo);
        log.info("当前注册用户数：{}", CommonConstant.SERVICE_USER_INFOS.size());
    }
}